{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Calysto Simulator\n", "\n", "Requires:\n", "\n", "* [metakernel](https://github.com/Calysto/metakernel)\n", "* [calysto](https://github.com/Calysto/calysto)\n", "\n", "Both can be installed via pip. These are already installed on Athena at Bryn Mawr College.\n", "\n", "For the %%brain magic, you need to use the calysto magics:\n", "\n", "```python\n", "from calysto import register_ipython_magics\n", "register_ipython_magics()\n", "```\n", "\n", "These are already loaded locally on the Athena server.\n", "\n", "You can also program the simulator without the magic, but it requires some boiler-plate code.\n", "\n", "## Start the simulator\n", "\n", "The simulator runs in a thread and has a GUI via the IPython widgets:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from calysto.simulation import View\n", "View(\"Bug1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You won't be able to see the simulation view above, unless you are running a live kernel. But it would look something like this:\n", "\n", "\n", "\n", "Animated:\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Write a brain controller\n", "\n", "Each robot/agent also runs in a thread. You can easily create a thread (with any error messages going to the simulator above) using the %%brain magic:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%%brain\n", "\n", "robot.forward(4)\n", "robot.sleep(7.5)\n", "robot.turnLeft(4.4)\n", "robot.forward(2)\n", "robot.turnRight(4.4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following methods on robot are defined:\n", "\n", "* forward(seconds)\n", "* backward(seconds)\n", "* turnLeft(seconds)\n", "* turnRight(seconds)\n", "* sleep(seconds)\n", "* stop()\n", "\n", "Senses:\n", "\n", "* takePicture() - returns a 256 x 128 image from agent's camera\n", "* getIR(position) - floating point numbers indicating 0 to 1 obstacle (1 means no obstacle, less than 1 means detection, with lower meaning closer)\n", "* stalled - Boolean indicating bumping against something\n", "\n", "You can define a simulation file like Bug1.py:\n", "\n", "```python\n", "from calysto.simulation import LadyBug, Spider, Simulation, Color\n", "import math\n", "\n", "def makeSimulation():\n", " ladybug = LadyBug(550, 350, -math.pi/2)\n", " spider = Spider(50, 50, 0)\n", " def spiderBrain():\n", " direction = 1\n", " while simulation.is_running.is_set():\n", " if spider.stalled:\n", " direction = direction * -1\n", " if direction == 1:\n", " spider.forward(1)\n", " else:\n", " spider.backward(1)\n", " spider.stop()\n", " spider.brain = spiderBrain\n", " simulation = Simulation(600, 400, ladybug, spider)\n", " simulation.makeWall(500, 100, 10, 200, Color(255, 255, 0))\n", " simulation.makeWall(10, 100, 190, 10, Color(255, 255, 0))\n", " simulation.makeWall(300, 100, 200, 10, Color(255, 255, 0))\n", " simulation.makeWall(100, 300, 410, 10, Color(255, 255, 0))\n", " simulation.makeWall(10, 200, 390, 10, Color(255, 255, 0))\n", " return simulation\n", "```\n", "\n", "There are three robots types:\n", "\n", "* Spider\n", "* LadyBug\n", "* Robot - based on the Scribbler/IPRE robot\n", "\n", "## Implementation details\n", "\n", "Some effort has been taken to reduce the load on the server, and between notebook and kernel. \n", "\n", "* minimum update computation: computes collisions, and IR hits\n", "* camera images taken on request (expensive)\n", "* simulator view is transfered to notebook as SVG for efficient size and speed\n", "* each controller/brain runs in its own thread\n", "\n", "### Variations\n", "\n", "You can use the simulator in a variety of styles, including without graphics, faster than real time, multiple controllers, etc.\n", "\n", "Here is an example getting an image from the LadyBug's camera:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from calysto.simulation import get_robot\n", "from calysto.display import display" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAACACAIAAABr1yBdAAAFAklEQVR4nO3cUUslZRzH8f/YvhUv\nvPDCCwklI0MwQ0JFROUgIq6JqNdFN/+b2NewL6CLLroINtpdSkxka2OJiiUqJJaIiqjewTl2MXJ2\nzjxz1M56zjMzv++Hw+E/s4s+MzzfHVnUxMwNUDUUewFATAQAaQQAaQQAaQQAaQQAaQQAaQQAacnZ\nWcfx+fnFMDzsA18M0EeH9m94smsA7aHwZHsYGfGbWyHQi337O3cmsST8a8UnXzCAbkP6PjrqV6wd\nuIY9+yt7mNvK4c4uSwC5w+z72JiHq4GyXfuzPV++xesQQO49HcbHPVwi6mfHfm/P7X2Z3aCiAYSH\nExMeLhrVsm2/pcPle50ACg5z89SUh9eAstmyX9Mh3XPhFieAHgPIHU5Pe3hJGLxNe5YOhTueAPoV\nQPs1M+PhtaHfNuyX6+x4Auh7AO1Xq2Vzcx5eJ25Kw84ss7MJoHiIGEB7np/38ILRm3X7ObubCeCK\noQwBpHOrZYuLHl45rmPVfizc6wRwxVCqANL35WUPrx/drNgP6f4mgJoEkL63Wra25uGNQGrZnmY3\nNwEUn6x0AOnQaHh4O5Qt2ffhjieA4pM1CCB9bW56eFPULNi32e1OAB1D4cnaBNBsWqtlt297eGsU\nvGXf5La+WgD8RJiZ2d27HnsJEczbk9hLiI8nwPOh2bSDA+/hJlbOm/Z1+o/3kA3xBICWN+yr2Eso\nEQLQMmtfxl5CudyKvYCyu3Ppb88ueKZezzsD/6XcM3aaWMI/eTkE0OHy7V5dr9sJW78QN6X+XrPj\n2EsoLwKI471BPWpetaPBfKKKIoA6e8U+i72EsiOA2pq0h7GXUAEEAGn8L1A0L9unffrI53aeWGL2\nUp8+fp3wBIA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0\nAoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0\nAoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoA0AoC0W7EX\noOuxP+7rx5/0yb5+/HrgCQBpBFBbj/xR7CVUAAHU2amfxl5C2RFAHO/7gD7RiZ8M6DNVEwHU37Ef\nx15CefG/QB3e9fyZO8GZKjryoxmfib2KMkrOzjqOz8/zQ+HJK4fCw0veux2Gc3iYfbVa+Tn3nh1a\nLWs2nw/Nph3808tNrJBZn00sGbKhxJLskHuZWeFhOmTfs4e5P+12mB2uPNnDYeGZbif5EkjLA38Q\newnlQgBy7vv92EsoEb4Euhje/qOX21dp8z7Pl0A8AcxMcfeb2T2/F3sJ8ak/ATaf9XDT6mbBF2Sf\nALoBNDovHEu+RAASAaz9FN4HXFj2ZQLoGApPVjGA5afh5aOrFV8hgK4nqxXA4nfhheNaVn2VAKoa\nwPyT8HrRo3VfJ4BqBDDX3x+0UtfwhhFA2QKY4fveY9jwDQIoHgYTwPQX4RUhgk3fTAcC6G8AU5+H\nl4DS2fKtdCCAFw1ggm9erL5t304HAuj6ng7jn4QrRA3t+E57Fg1g7ONwMZC267vtuSYBjH4Ufkbg\nf9vzvexhiQIY+bD7qoGB2Pf93JkbCGD4gxtZG1AWh34YnkzMB74QoDT4iTBIIwBIIwBIIwBIIwBI\nIwBIIwBI+w+w+51wyvco0wAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "with get_robot() as robot:\n", " display(robot.takePicture())" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }